<?php

/**
 * @author ntourne
 * @date 23/05/2011
 * Manejo del objeto User
 */

class User extends Entity {

	var $userVO;
	
	function __construct($userVO = null) {
		parent::__construct();
		$this->userVO = $userVO;
	}

	
	function setVO($userVO) {
		$this->userVO = $userVO;
	}
	
	
	/**
	 * Validate input data for Login
	 * @return true if User's data validates
	 */
	function validateLogin() {

		// validate username		
		if (Validation::isEmptyString($this->userVO->username))
			$this->addMessage(MessageLabel::$USERNAME_OR_EMAIL_CANT_EMPTY);
			
		// validate password
		if (Validation::isEmptyString($this->userVO->password))
			$this->addMessage(MessageLabel::$PASSWORD_CANT_EMPTY);
		
		return Validation::isEmptyArray($this->messages);
	}
	

	static function populateVO($row) {
		$userVO = new UserVO();
		$userVO->id = $row['id'];
		$userVO->username = $row['username'];
		$userVO->password = $row['password'];
		$userVO->email = $row['email'];
		$userVO->screenname = $row['screenname'];
		$userVO->resume = $row['resume'];
		$userVO->website = $row['website'];
		$userVO->creationdate = $row['creationdate'];
		$userVO->activationdate = $row['activationdate'];
		$userVO->status = $row['status'];
		$userVO->token = $row['token'];
		return $userVO;
	}
	
	
	/**
	 * Login user
	 * @return true if User's exists and login is successfull
	 */
	function login() {
		
		// if username + password exists
		if ($this->getUserByUsernamePassword()) {
			
			// update lastLogin and lastIpAddress
			$this->updateLoginInfo();
			
			$_SESSION['user_logged'] = 1;
			$_SESSION['userid'] = $this->userVO->id;
			$_SESSION['username'] = $this->userVO->username;
			$_SESSION['screenname'] = $this->userVO->screenname;
			
			return true;
		}
		return false;
		
	}
	
	
	/**
	 * Update login info access (lastLogin and lastIpAddress)
	 */
	function updateLoginInfo() {
	/*	$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();
		
		$dbUtil->setSPName("UPD_UserLoginInfo");
		$dbUtil->setParameter($this->id, ParameterDB::INT_TYPE);
		$dbUtil->setParameter($this->lastIpAddress, ParameterDB::VARCHAR_TYPE);
		$dbUtil->setParameter(date('Y-m-d H:i:s'), ParameterDB::DATETIME_TYPE);
		
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$db->close_connection();
		
		return true;*/
	}	
	
	
	/**
	 * Login user
	 * @return true if User's exists and login is successfull
	 */
	function logout() {
		
		$_SESSION = array();
		session_destroy();
		
	}	
	
	
	/**
	 * Save User's info (signup or edit)
	 */
	function saveUser() {
		$success = false;
		if (Validation::isEmptyString($this->id))
			$success = $this->insertUser();
		else 
			$success = $this->updateUser();
		return $success;
	}
	
	
	/**
	 * Insert a new User (signup)
	 */
	function insertUser() {
		
		$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();

		$token = $this->generateToken();
		
		$dbUtil->setSPName("INS_User");
		$dbUtil->setParameter(Security::prevenirSqlInjection($this->username), ParameterDB::VARCHAR_TYPE);
		$dbUtil->setParameter(md5(Security::prevenirSqlInjection($this->password)), ParameterDB::VARCHAR_TYPE);
		$dbUtil->setParameter(Security::prevenirSqlInjection($this->email), ParameterDB::VARCHAR_TYPE);
		$dbUtil->setParameter($this->countryId, ParameterDB::INT_TYPE);
		$dbUtil->setParameter($this->gender, ParameterDB::CHAR_TYPE);
		$dbUtil->setParameter(0, ParameterDB::BOOLEAN_TYPE);	// verifiedmail
		$dbUtil->setParameter($this->lastIpAddress, ParameterDB::VARCHAR_TYPE);
		$dbUtil->setParameter(date('Y-m-d H:i:s'), ParameterDB::DATETIME_TYPE);	// lastLogin
		$dbUtil->setParameter(date('Y-m-d H:i:s'), ParameterDB::DATETIME_TYPE);
		$dbUtil->setParameter(Status::NEW_STATUS, ParameterDB::INT_TYPE);
		$dbUtil->setParameter($token, ParameterDB::VARCHAR_TYPE);
		
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		// get last insert ID
		$this->lastUserId = $this->getLastInsertID($conn);
		
		$db->close_connection();
		
		// send Signup email
		EmailManager::sendSignup($this->email, $token);
		
		return true;
	}

	
	/**
	 * Get all Users that match with username OR email
	 * @return List<User>
	 */
	function getUsersByUsernameEmail() {

		$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();

		$dbUtil->setSPName("QRY_UserByUsernameEmail");
		$dbUtil->setParameter(Security::prevenirSqlInjection($this->username), ParameterDB::VARCHAR_TYPE);
		$dbUtil->setParameter(Security::prevenirSqlInjection($this->email), ParameterDB::VARCHAR_TYPE);		
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$users = array();
		while ($row = mysql_fetch_array($sql)) {
			$users[] = $row;
		}
				
		$db->close_connection();
		
		return $users;
				
	}
	
	
	/**
	 * Get User that match with email
	 * @return User
	 */
	function getUserByEmail() {

		$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();

		$dbUtil->setSPName("QRY_UserByEmail");
		$dbUtil->setParameter(trim(Security::prevenirSqlInjection($this->email)), ParameterDB::VARCHAR_TYPE);		
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$row = mysql_fetch_array($sql);
		$db->close_connection();
		if ($row == null)
			return false;
		
		$this->id = $row['id'];
		$this->username = $row['username'];
		$this->email = $row['email'];
		$this->status = $row['status'];
		$this->token = $row['token'];
		
		return true;
		
	}

	
	/**
	 * Get User by ID
	 * @return User
	 */
	function getUserByID() {

		$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();

		$dbUtil->setSPName("QRY_UserById");
		$dbUtil->setParameter($this->id, ParameterDB::INT_TYPE);
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$row = mysql_fetch_array($sql);
		$db->close_connection();
		if ($row == null)
			return false;
		
		$this->id = $row['id'];
		$this->username = $row['username'];
		$this->email = $row['email'];
		$this->reviewsLeft = $row['reviewsLeft'];
		$this->commentsLeft = $row['commentsLeft'];
		$this->subscribesCount = $row['subscribesCount'];
		$this->status = $row['status'];
		$this->token = $row['token'];
		
		return true;
	}
	
	
	
	/**
	 * Get User by username
	 * @return User
	 */
	static function getUserByUsername($userVO, $display) {

		$db = new DBManager();
		$conn = $db->getConnection();
		$dbUtil = new DBUtil();

		$dbUtil->setSPName("SEL_UserByUsername");
		$dbUtil->setParameter($userVO->username, ParameterDB::VARCHAR_TYPE);
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$row = mysql_fetch_array($sql);
		$db->closeConnection();
		if ($row == null)
			return false;
		
		$userVO = User::populateVO($row);
		
		if ($display == "profile") {
			$commentVO = new CommentVO();
			$commentVO->user_username = $userVO->username;
			$comments = Comment::getCommentsByUsername($commentVO);
			foreach($comments as $commentVO) {
				$commentVO->linkifyMsg();
			}
			$userVO->comments = $comments;
		}
			
		return $userVO;
	}
	
	
	/**
	 * Get User ID by token
	 * @return int $userID
	 */
	function getUserIdByToken() {

		$db = new ManagerDB();
		$conn = $db->getConnection();
		$dbUtil = new DBUtil();

		$dbUtil->setSPName("QRY_UserIdByToken");
		$dbUtil->setParameter(Security::prevenirSqlInjection($this->token), ParameterDB::VARCHAR_TYPE);
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$row = mysql_fetch_array($sql);
		$db->close_connection();
		if ($row == null)
			return false;

		$this->id = $row['id'];
		
		return true;				
	}
	
	
	/**
	 * Get User by username+password, used for login
	 * @return User
	 */
	function getUserByUsernamePassword() {

		$db = new DBManager();
		$conn = $db->getConnection();
		$dbUtil = new DBUtil();

		$dbUtil->setSPName("SEL_UserByUsernameEmailPassword");
		$dbUtil->setParameter(Security::preventSqlInjection($this->userVO->username), ParameterDB::VARCHAR_TYPE);
		$dbUtil->setParameter(md5(Security::preventSqlInjection($this->userVO->password)), ParameterDB::VARCHAR_TYPE);
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$row = mysql_fetch_array($sql);
		$db->closeConnection();
		if ($row == null)
			return false;
		
		$this->userVO = new UserVO($row);

		return true;				
	}
	
	
	/**
	 * Activate a User
	 */
	function activate() {

		// validate if a user with this token exists
		if ($this->getUserIdByToken($this->token)) {

			$this->getUserById();
			
			// check if the user is already activated 
			if ($this->status == Status::ACTIVE_STATUS) {
				$this->addMessage(Message::$ACCOUNT_ALREADY_ACTIVATED); // array("type" => MessageType::ERROR, "text" => "This account is already activated");
				return false;
				
			} else {
				// update token column if token matches
				$this->updateActivateUserStatus();
				$this->addMessage(Message::$CONGRATULATIONS_ACCOUNT_ACTIVATED); // array("type" => MessageType::SUCCESS, "text" => "Congratulations! Your account has been successfully activated");
				return true;
			}
		}
		else {
			$this->addMessage(Message::$ACCOUNT_NOT_ACTIVATED_TOKEN_NOT_VALID); // array("type" => MessageType::ERROR, "text" => "Your account has not been activated. The token is not valid");
			return false;
		}
	}
	
	
	/**
	 * Activate a User status to ACTIVATE if token matches
	 */
	function updateActivateUserStatus() {
		$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();
		
		$dbUtil->setSPName("UPD_UserActivate");
		$dbUtil->setParameter(Security::prevenirSqlInjection($this->token), ParameterDB::VARCHAR_TYPE);
		
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$db->close_connection();
		
		return true;
	}

	
	/**
	 * Return reviews left by a User
	 * @return List<Review> 
	 */
	function getReviewsLeft() {

		$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();

		$dbUtil->setSPName("QRY_UserReviewsLeft");
		$dbUtil->setParameter($this->id, ParameterDB::INT_TYPE);
		$dbUtil->setParameter($this->limitInf, ParameterDB::INT_TYPE);
		$dbUtil->setParameter($this->limitSup, ParameterDB::INT_TYPE);		
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$reviews = array();
		while ($row = mysql_fetch_array($sql)) {
			$row['points'] = Utilities::normalizePoints($row['points']);
			$row['timeago'] = Utilities::getTimeAgo($row['creationDate']);
			$reviews[] = $row;
		}
				
		$db->close_connection();
		
		return $reviews;
	}

	
	/**
	 * Return reviews couunt left by a User
	 * @return int
	 */
	function getReviewsLeftCount() {

		$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();

		$dbUtil->setSPName("QRY_UserReviewsLeftCount");
		$dbUtil->setParameter($this->id, ParameterDB::INT_TYPE);		
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$row = mysql_fetch_array($sql);
		$db->close_connection();
		
		if ($row == null)
			return 0;		
		
		return $row['count'];	
	}
		
	
	/**
	 * Return comments left by a User
	 * @return List<Comment> 
	 */
	function getCommentsLeft() {

		$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();

		$dbUtil->setSPName("QRY_UserCommentsLeft");
		$dbUtil->setParameter($this->id, ParameterDB::INT_TYPE);
		$dbUtil->setParameter($this->limitInf, ParameterDB::INT_TYPE);
		$dbUtil->setParameter($this->limitSup, ParameterDB::INT_TYPE);		
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());

		$db->close_connection();
		
		$comments = array();
		while ($row = mysql_fetch_array($sql)) {
			$row['timeago'] = Utilities::getTimeAgo($row['creationDate']);
			
			$row['showLike'] = 1;
			if (UserLogin::isUserLoggedin()) {
				
				$person = new Person();
				$person->commentId = $row['id'];
				
				// TODO run a new query for each comment !!
				if ($person->isAlreadyLikeComment()) {
					$row['showLike'] = 0;
				}
			}
			
			$comments[] = $row;
		}
				
		return $comments;
	}

	
	/**
	 * Return comments left by a User
	 * @return int
	 */
	function getCommentsLeftCount() {

		$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();

		$dbUtil->setSPName("QRY_UserCommentsLeftCount");
		$dbUtil->setParameter($this->id, ParameterDB::INT_TYPE);
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$row = mysql_fetch_array($sql);
		$db->close_connection();
		
		if ($row == null)
			return 0;		
		
		return $row['count'];	
	}	
	
	
	/**
	 * Send an email with link to reset password
	 */
	function sendRecoverPasswordEmail() {
		
		// generate new token and save into the User
		$this->token = $this->generateToken();
		$this->updateUserToken();
		
		return EmailManager::sendResetPassword($this->email, $this->token);		
	}
	
	
	/**
	 * Update User's token
	 */
	function updateUserToken() {
		$db 	= new ManagerDB();
		$conn 	= $db->getConnection();
		$dbUtil = new DBUtil();
		
		$dbUtil->setSPName("UPD_UserToken");
		$dbUtil->setParameter($this->id, ParameterDB::INT_TYPE);
		$dbUtil->setParameter(Security::prevenirSqlInjection($this->token), ParameterDB::VARCHAR_TYPE);
		
		$sent = $dbUtil->generateSP();
		$sql = mysql_query($sent, $conn) or die (mysql_error());
		
		$db->close_connection();
		
		return true;
	}
	
}


/**
 * @author ntourne
 * Manejo del objeto UserVO
 */
class UserVO {
	
	var $id;
	var $username;
	var $password;
	var $email;
	var $screenname;
	var $resume;
	var $website;
	var $creationdate;
	var $activationdate;
	var $status;
	var $token;
	
	var $comments;

	
	function __construct($u = null) {
		if ($u != null) {
			$this->id = $u['id'];
			$this->username = $u['username'];
			$this->password = $u['password'];
			$this->email = $u['email'];
			$this->screenname = $u['screenname'];
			$this->resume = $u['resume'];
			$this->website = $u['website'];
			$this->creationdate = $u['creationdate'];
			$this->activationdate = $u['activationdate'];
			$this->status = $u['status'];
			$this->token = $u['token'];
		}
	}
	
	
}